package game;

import game.model.Actor;

import java.util.Vector;

/**
 * 
 */

/**
 * @author Quynh Lam
 * 
 */
public class Util {
    private static short sin[] = { 0, 18, 36, 54, 71, 89, 107, 125, 143, 160, 178, 195, 213, 230, 248, 265, 282, 299, 316, 333, 350, 367, 384, 400, 416, 433, 449, 465, 481, 496, 512, 527, 543, 558, 573, 587, 602, 616, 630, 644, 658, 672, 685, 698, 711, 724, 737, 749, 761, 773, 784, 796, 807, 818, 828, 839, 849, 859, 868, 878, 887, 896, 904, 912, 920, 928, 935, 943, 949, 956, 962, 968, 974, 979, 984, 989, 994, 998, 1002, 1005, 1008, 1011, 1014, 1016, 1018, 1020, 1022, 1023, 1023, 1024, 1024 };
    private static short cos[];
    private static int tan[];
    static {
        cos = new short[91];
        tan = new int[91];
        for (int i = 0; i <= 90; i++) {
            cos[i] = sin[90 - i];
            if (cos[i] == 0)
                tan[i] = Integer.MAX_VALUE;
            else
                tan[i] = (sin[i] << 10) / cos[i];
        }
    }

    // tinh sin goc 0-359
    public static final int sin(int a) {
        if (a >= 0 && a < 90)
            return sin[a];
        if (a >= 90 && a < 180)
            return sin[180 - a];
        if (a >= 180 && a < 270)
            return -sin[a - 180];
        return -sin[360 - a];
    }

    // tinh cos goc 0-359
    public static final int cos(int a) {
        if (a >= 0 && a < 90)
            return cos[a];
        if (a >= 90 && a < 180)
            return -cos[180 - a];
        if (a >= 180 && a < 270)
            return -cos[a - 180];
        return cos[360 - a];
    }

    // tinh tan goc 0-359
    public static final int tan(int a) {
        if (a >= 0 && a < 90)
            return tan[a];
        if (a >= 90 && a < 180)
            return -tan[180 - a];
        if (a >= 180 && a < 270)
            return tan[a - 180];
        return -tan[360 - a];
    }

    public static final int atan(int a) {
        for (int i = 0; i <= 90; i++)
            if (tan[i] >= a)
                return i;
        return 0;
    }

    // tinh goc tao boi dx, dy
    public static final int angle(int dx, int dy) {
        int angle;
        if (dx != 0) {
            int tan = Math.abs((dy << 10) / dx);
            angle = atan(tan);
            if (dy >= 0 && dx < 0)
                angle = 180 - angle;
            if (dy < 0 && dx < 0)
                angle = 180 + angle;
            if (dy < 0 && dx >= 0)
                angle = 360 - angle;
            // System.out.println(a+" "+angle);
        } else {
            angle = dy > 0 ? 90 : 270;
        }
        return angle;
    }

    // dieu chinh lai goc <0 hoac >360 ve trong khoang 0-360
    public static final int fixangle(int angle) {
        if (angle >= 360)
            angle -= 360;
        if (angle < 0)
            angle += 360;
        return angle;
    }

    // tinh hieu cua 2 goc
    public static final int subangle(int a1, int a2) {
        int a = a2 - a1;
        if (a < -180)
            return a + 360;
        if (a > 180)
            return a - 360;
        return a;
    }

    public static boolean inDataRange(Actor p1, Actor p2) {
        return (Math.abs(p1.x - p2.x) < 256 && Math.abs(p1.y - p2.y) < 256);
    }

    public static void quickSort(Vector actors) {
        recQuickSort(actors, 0, actors.size() - 1);
    }

    private static void recQuickSort(Vector actors, int left, int right) {
        if (right - left <= 0)
            return;
        else {
            int pivot = ((Actor) actors.elementAt(right)).y;

            int partition = partitionIt(actors, left, right, pivot);
            recQuickSort(actors, left, partition - 1);
            recQuickSort(actors, partition + 1, right);
        }
    }

    private static int partitionIt(Vector actors, int left, int right, int pivot) {
        int leftPtr = left - 1;
        int rightPtr = right;
        while (true) {
            while (((Actor) actors.elementAt(++leftPtr)).y < pivot)
                ;

            while (rightPtr > 0 && ((Actor) actors.elementAt(--rightPtr)).y > pivot)
                ;

            if (leftPtr >= rightPtr)
                break;
            else
                swap(actors, leftPtr, rightPtr);
        }
        swap(actors, leftPtr, right);
        return leftPtr;
    }

    private static void swap(Vector actors, int dex1, int dex2) {
        Object temp = actors.elementAt(dex2);
        actors.setElementAt(actors.elementAt(dex1), dex2);
        actors.setElementAt(temp, dex1);
    }

    public static int abs(int x) {
        return x > 0 ? x : -x;
    }

    public static short findDirection(Actor from, Actor lookTo) {
        try {
            if (abs(from.x - lookTo.x) < abs(from.y - lookTo.y))
                if (lookTo.y > from.y)
                    return 0;
                else
                    return 1;
            else if (lookTo.x < from.x)
                return 2;
            return 3;
        } catch (Exception e) {
            return 0;
        }
    }

}
